package com.xiaoshuidi.cloud.module.contract.mq.consumer;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xiaoshuidi.cloud.framework.common.util.json.JsonUtils;
import com.xiaoshuidi.cloud.module.contract.dal.dataobject.bill.OrderFeesDO;
import com.xiaoshuidi.cloud.module.contract.dal.dataobject.bill.RentOrderDO;
import com.xiaoshuidi.cloud.module.contract.dal.dataobject.contract.ContractApplyDO;
import com.xiaoshuidi.cloud.module.contract.dal.mysql.bill.OrderFeesMapper;
import com.xiaoshuidi.cloud.module.contract.dal.mysql.bill.RentOrderMapper;
import com.xiaoshuidi.cloud.module.contract.enums.bill.OrderPayStatusEnum;
import com.xiaoshuidi.cloud.module.contract.enums.bill.OrderTypeEnum;
import com.xiaoshuidi.cloud.module.contract.enums.contract.ContractApplyStatus;
import com.xiaoshuidi.cloud.module.contract.enums.contract.ContractApplyType;
import com.xiaoshuidi.cloud.module.contract.service.contract.ContractApplyService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * @Author Feng
 * @date 2023/7/5
 */
@Slf4j
@Component("contractApplyConsumer")
@RequiredArgsConstructor
public class ContractApplyConsumer implements Consumer<Long> {
    private final ContractApplyService contractApplyService;
    private final RentOrderMapper rentOrderMapper;
    private final OrderFeesMapper orderFeesMapper;

    @Override
    @Transactional
    public void accept(Long id) {
        log.info("延期申请到期取消");
        ContractApplyDO applyDO = contractApplyService.getById(id);
        if (applyDO == null) {
            log.info("延期申请不存在：{}", id);
            return;
        }
        log.info("applyDO: {}", JsonUtils.toJsonString(applyDO));
        if (!ContractApplyType.EXTENSION.getCode().equals(applyDO.getApplyType())) {
            log.info("非延期申请,无需处理： {}", ContractApplyType.getMsgByCode(applyDO.getApplyType()));
            return;
        }
        if (!applyDO.getApplyStatus().equals(ContractApplyStatus.TO_BE_EFFECTIVE.getCode())) {
            log.info("该延期申请,不是待生效状态,无需处理：{}", ContractApplyStatus.getMsgByCode(applyDO.getApplyStatus()));
            return;
        }
        ContractApplyDO updateApplyDo = new ContractApplyDO();
        updateApplyDo.setId(applyDO.getId());
        //取消账单
        RentOrderDO rentOrderDO = this.rentOrderMapper.selectById(applyDO.getRentOrderId());
        if (rentOrderDO == null) {
            updateApplyDo.setApplyStatus(ContractApplyStatus.CANCELED.getCode());
        } else {
            if (OrderPayStatusEnum.PAID.getCode().equals(rentOrderDO.getPayStatus())) {
                //账单已支付: 申请生效
                updateApplyDo.setApplyStatus(ContractApplyStatus.EFFECTIVE.getCode());
            } else {
                updateApplyDo.setApplyStatus(ContractApplyStatus.CANCELED.getCode());
                //取消账单明细
                LambdaQueryWrapper<OrderFeesDO> wrapper = Wrappers.lambdaQuery();
                wrapper.eq(OrderFeesDO::getOrderId, rentOrderDO.getId())
                        .eq(OrderFeesDO::getOrderType, OrderTypeEnum.EXTENSION.getCode());
                List<OrderFeesDO> orderFeesDOS = orderFeesMapper.selectList(wrapper);
                if (CollectionUtil.isNotEmpty(orderFeesDOS)) {
                    List<OrderFeesDO> updateFeesList = orderFeesDOS.stream().map(s -> {
                        OrderFeesDO updateFeesDo = new OrderFeesDO();
                        updateFeesDo.setPayStatus(OrderPayStatusEnum.CANCEL.getCode());
                        updateFeesDo.setId(s.getId());
                        return updateFeesDo;
                    }).collect(Collectors.toList());
                    orderFeesMapper.updateBatch(updateFeesList, updateFeesList.size());
                }
                RentOrderDO updateOrder = new RentOrderDO();
                updateOrder.setId(rentOrderDO.getId());
                updateOrder.setPayStatus(OrderPayStatusEnum.CANCEL.getCode());
                rentOrderMapper.updateById(updateOrder);
            }
        }
        //取消申请
        contractApplyService.updateById(updateApplyDo);
        log.info("延期申请取消成功");
    }
}
